﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.model;
using l1cs.server.serverpackets;
using l1cs.server.datatables;
using l1cs.server.templates;
using System.IO;
using l1cs.server.model.map;

namespace l1cs.server.clientpackets
{
    public class C_Attr : ClientBasePacket
    {
        private static Logger _log = Logger.getLogger( typeof( C_Attr ).FullName );
        private const String _C_ATTR = "[C] C_Attr";

        private static int[] HEADING_TABLE_X = { 0, 1, 1, 1, 0, -1, -1, -1 };
        private static int[] HEADING_TABLE_Y = { -1, -1, 0, 1, 1, 1, 0, -1 };

        public C_Attr( byte[] abyte0, ClientThread clientthread )
            : base( abyte0 )
        {
            int i = readH();
            int c;
            String name;
            String clanName;
            L1PcInstance pc = clientthread.getActiveChar();

            switch ( i )
            {
                case 97: // %0が血盟に加入したがっています。承諾しますか？（Y/N）
                    c = readC();
                    L1PcInstance joinPc = (L1PcInstance)L1World.getInstance().findObject( pc.getTempID() );
                    pc.setTempID( 0 );
                    if ( joinPc != null )
                    {
                        if ( c == 0 )
                        { // No
                            joinPc.sendPackets( new S_ServerMessage( 96, pc.getName() ) ); // \f1%0はあなたの要請を拒絶しました。
                        }
                        else if ( c == 1 )
                        { // Yes
                            int clan_id = pc.getClanid();
                            clanName = pc.getClanname();
                            L1Clan clan = L1World.getInstance().getClan( clanName );
                            if ( clan != null )
                            {
                                int maxMember = 0;
                                int charisma = pc.getCha();
                                bool lv45quest = false;
                                if ( pc.getQuest().isEnd( L1Quest.QUEST_LEVEL45 ) )
                                {
                                    lv45quest = true;
                                }
                                if ( pc.getLevel() >= 50 )
                                { // Lv50以上
                                    if ( lv45quest == true )
                                    { // Lv45クエストクリア済み
                                        maxMember = charisma * 9;
                                    }
                                    else
                                    {
                                        maxMember = charisma * 3;
                                    }
                                }
                                else
                                { // Lv50未満
                                    if ( lv45quest == true )
                                    { // Lv45クエストクリア済み
                                        maxMember = charisma * 6;
                                    }
                                    else
                                    {
                                        maxMember = charisma * 2;
                                    }
                                }
                                if ( Config.MAX_CLAN_MEMBER > 0 )
                                { // Clan人数の上限の設定あり
                                    maxMember = Config.MAX_CLAN_MEMBER;
                                }

                                if ( joinPc.getClanid() == 0 )
                                { // クラン未加入
                                    String[] clanMembersName = clan.getAllMembers();
                                    if ( maxMember <= clanMembersName.Length )
                                    { // 空きがない
                                        joinPc.sendPackets( // %0はあなたを血盟員として受け入れることができません。
                                                new S_ServerMessage( 188, pc.getName() ) );
                                        return;
                                    }
                                    foreach ( L1PcInstance clanMembers in clan.getOnlineClanMember() )
                                    {
                                        clanMembers.sendPackets( new S_ServerMessage( 94, joinPc.getName() ) ); // \f1%0が血盟の一員として受け入れられました。
                                    }
                                    joinPc.setClanid( clan_id );
                                    joinPc.setClanname( clanName );
                                    joinPc.setClanRank( L1Clan.CLAN_RANK_PUBLIC );
                                    joinPc.setTitle( "" );
                                    joinPc.sendPackets( new S_CharTitle( joinPc.getId(), "" ) );
                                    joinPc.broadcastPacket( new S_CharTitle( joinPc.getId(), "" ) );
                                    joinPc.save(); // DBにキャラクター情報を書き込む
                                    clan.addMemberName( joinPc.getName() );
                                    joinPc.sendPackets( new S_ServerMessage( 95, clanName ) ); // \f1%0血盟に加入しました。
                                }
                                else
                                { // クラン加入済み（クラン連合）
                                    if ( Config.CLAN_ALLIANCE )
                                    {
                                        changeClan( clientthread, pc, joinPc, maxMember );
                                    }
                                    else
                                    {
                                        joinPc.sendPackets( new S_ServerMessage( 89 ) ); // \f1あなたはすでに血盟に加入しています。
                                    }
                                }
                            }
                        }
                    }
                    break;

                case 217: // %0血盟の%1があなたの血盟との戦争を望んでいます。戦争に応じますか？（Y/N）
                case 221: // %0血盟が降伏を望んでいます。受け入れますか？（Y/N）
                case 222: // %0血盟が戦争の終結を望んでいます。終結しますか？（Y/N）
                    c = readC();
                    L1PcInstance enemyLeader = (L1PcInstance)L1World.getInstance().findObject( pc.getTempID() );
                    if ( enemyLeader == null )
                    {
                        return;
                    }
                    pc.setTempID( 0 );
                    clanName = pc.getClanname();
                    String enemyClanName = enemyLeader.getClanname();
                    if ( c == 0 )
                    { // No
                        if ( i == 217 )
                        {
                            enemyLeader.sendPackets( new S_ServerMessage( 236, clanName ) ); // %0血盟があなたの血盟との戦争を拒絶しました。
                        }
                        else if ( i == 221 || i == 222 )
                        {
                            enemyLeader.sendPackets( new S_ServerMessage( 237, clanName ) ); // %0血盟があなたの提案を拒絶しました。
                        }
                    }
                    else if ( c == 1 )
                    { // Yes
                        if ( i == 217 )
                        {
                            L1War war = new L1War();
                            war.handleCommands( 2, enemyClanName, clanName ); // 模擬戦開始
                        }
                        else if ( i == 221 || i == 222 )
                        {
                            // 全戦争リストを取得
                            foreach ( L1War war in L1World.getInstance().getWarList() )
                            {
                                if ( war.CheckClanInWar( clanName ) )
                                { // 自クランが行っている戦争を発見
                                    if ( i == 221 )
                                    {
                                        war.SurrenderWar( enemyClanName, clanName ); // 降伏
                                    }
                                    else if ( i == 222 )
                                    {
                                        war.CeaseWar( enemyClanName, clanName ); // 終結
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    break;

                case 252: // %0%sがあなたとアイテムの取引を望んでいます。取引しますか？（Y/N）
                    c = readC();
                    L1PcInstance trading_partner = (L1PcInstance)L1World.getInstance().findObject( pc.getTradeID() );
                    if ( trading_partner != null )
                    {
                        if ( c == 0 ) // No
                        {
                            trading_partner.sendPackets( new S_ServerMessage( 253, pc.getName() ) ); // %0%dはあなたとの取引に応じませんでした。
                            pc.setTradeID( 0 );
                            trading_partner.setTradeID( 0 );
                        }
                        else if ( c == 1 ) // Yes
                        {
                            pc.sendPackets( new S_Trade( trading_partner.getName() ) );
                            trading_partner.sendPackets( new S_Trade( pc.getName() ) );
                        }
                    }
                    break;

                case 321: // また復活したいですか？（Y/N）
                    c = readC();
                    L1PcInstance resusepc1 = (L1PcInstance)L1World.getInstance().findObject( pc.getTempID() );
                    pc.setTempID( 0 );
                    if ( resusepc1 != null )
                    { // 復活スクロール
                        if ( c == 0 )
                        { // No
                            ;
                        }
                        else if ( c == 1 )
                        { // Yes
                            pc.sendPackets( new S_SkillSound( pc.getId(), 0xE6 ) ); //'\346'));
                            pc.broadcastPacket( new S_SkillSound( pc.getId(), 0xE6 ) ); //'\346'));
                            // pc.resurrect(pc.getLevel());
                            // pc.setCurrentHp(pc.getLevel());
                            pc.resurrect( pc.getMaxHp() / 2 );
                            pc.setCurrentHp( pc.getMaxHp() / 2 );
                            pc.startHpRegeneration();
                            pc.startMpRegeneration();
                            pc.startMpRegenerationByDoll();
                            pc.stopPcDeleteTimer();
                            pc.sendPackets( new S_Resurrection( pc, resusepc1, 0 ) );
                            pc.broadcastPacket( new S_Resurrection( pc, resusepc1, 0 ) );
                            pc.sendPackets( new S_CharVisualUpdate( pc ) );
                            pc.broadcastPacket( new S_CharVisualUpdate( pc ) );
                        }
                    }
                    break;

                case 322: // また復活したいですか？（Y/N）
                    c = readC();
                    L1PcInstance resusepc2 = (L1PcInstance)L1World.getInstance().findObject( pc.getTempID() );
                    pc.setTempID( 0 );
                    if ( resusepc2 != null )
                    { // 祝福された 復活スクロール、リザレクション、グレーター リザレクション
                        if ( c == 0 )
                        { // No
                            ;
                        }
                        else if ( c == 1 )
                        { // Yes
                            pc.sendPackets( new S_SkillSound( pc.getId(), 0xE6 ) ); //'\346'));
                            pc.broadcastPacket( new S_SkillSound( pc.getId(), 0xE6 ) ); //'\346'));
                            pc.resurrect( pc.getMaxHp() );
                            pc.setCurrentHp( pc.getMaxHp() );
                            pc.startHpRegeneration();
                            pc.startMpRegeneration();
                            pc.startMpRegenerationByDoll();
                            pc.stopPcDeleteTimer();
                            pc.sendPackets( new S_Resurrection( pc, resusepc2, 0 ) );
                            pc.broadcastPacket( new S_Resurrection( pc, resusepc2, 0 ) );
                            pc.sendPackets( new S_CharVisualUpdate( pc ) );
                            pc.broadcastPacket( new S_CharVisualUpdate( pc ) );
                            // EXPロストしている、G-RESを掛けられた、EXPロストした死亡
                            // 全てを満たす場合のみEXP復旧
                            if ( pc.getExpRes() == 1 && pc.isGres() && pc.isGresValid() )
                            {
                                pc.resExp();
                                pc.setExpRes( 0 );
                                pc.setGres( false );
                            }
                        }
                    }
                    break;

                case 325: // 動物の名前を決めてください：
                    c = readC(); // ?
                    name = readS();
                    L1PetInstance pet = (L1PetInstance)L1World.getInstance().findObject( pc.getTempID() );
                    pc.setTempID( 0 );
                    renamePet( pet, name );
                    break;

                case 512: // 家の名前は？
                    c = readC(); // ?
                    name = readS();
                    int houseId = pc.getTempID();
                    pc.setTempID( 0 );
                    if ( name.Length <= 16 )
                    {
                        L1House house = HouseTable.getInstance().getHouseTable( houseId );
                        house.setHouseName( name );
                        HouseTable.getInstance().updateHouse( house ); // DBに書き込み
                    }
                    else
                    {
                        pc.sendPackets( new S_ServerMessage( 513 ) ); // 家の名前が長すぎます。
                    }
                    break;

                case 630: // %0%sがあなたと決闘を望んでいます。応じますか？（Y/N）
                    c = readC();
                    L1PcInstance fightPc = (L1PcInstance)L1World.getInstance()
                            .findObject( pc.getFightId() );
                    if ( c == 0 )
                    {
                        pc.setFightId( 0 );
                        fightPc.setFightId( 0 );
                        fightPc.sendPackets( new S_ServerMessage( 631, pc.getName() ) ); // %0%dがあなたとの決闘を断りました。
                    }
                    else if ( c == 1 )
                    {
                        fightPc.sendPackets( new S_PacketBox( S_PacketBox.MSG_DUEL,
                                fightPc.getFightId(), fightPc.getId() ) );
                        pc.sendPackets( new S_PacketBox( S_PacketBox.MSG_DUEL, pc
                                .getFightId(), pc.getId() ) );
                    }
                    break;

                case 653: // 離婚をするとリングは消えてしまいます。離婚を望みますか？（Y/N）
                    c = readC();
                    L1PcInstance target653 = (L1PcInstance)L1World.getInstance().findObject( pc.getPartnerId() );
                    if ( c == 0 )
                    { // No
                        return;
                    }
                    else if ( c == 1 )
                    { // Yes
                        if ( target653 != null )
                        {
                            target653.setPartnerId( 0 );
                            target653.save();
                            // \f1あなたは結婚していません。
                            target653.sendPackets( new S_ServerMessage( 662 ) );
                        }
                        else
                        {
                            CharacterTable.updatePartnerId( pc.getPartnerId() );
                        }
                    }
                    pc.setPartnerId( 0 );
                    pc.save(); // DBにキャラクター情報を書き込む
                    pc.sendPackets( new S_ServerMessage( 662 ) ); // \f1あなたは結婚していません。
                    break;

                case 654: // %0%sあなたと結婚したがっています。%0と結婚しますか？（Y/N）
                    c = readC();
                    L1PcInstance partner = (L1PcInstance)L1World.getInstance().findObject( pc.getTempID() );
                    pc.setTempID( 0 );
                    if ( partner != null )
                    {
                        if ( c == 0 )
                        { // No
                            // %0%sはあなたとの結婚を拒絶しました。
                            partner.sendPackets( new S_ServerMessage( 656, pc.getName() ) );
                        }
                        else if ( c == 1 )
                        { // Yes
                            pc.setPartnerId( partner.getId() );
                            pc.save();
                            // 皆の祝福の中で、二人の結婚が行われました。                                    
                            pc.sendPackets( new S_ServerMessage( 790 ) );
                            // おめでとうございます！%0と結婚しました。                                    
                            pc.sendPackets( new S_ServerMessage( 655, partner.getName() ) );

                            partner.setPartnerId( pc.getId() );
                            partner.save();
                            // 皆の祝福の中で、二人の結婚が行われました。
                            partner.sendPackets( new S_ServerMessage( 790 ) );
                            // おめでとうございます！%0と結婚しました。
                            partner.sendPackets( new S_ServerMessage( 655, pc.getName() ) );

                        }
                    }
                    break;

                // コールクラン
                case 729: // 君主が呼んでいます。召喚に応じますか？（Y/N）
                    c = readC();
                    if ( c == 0 )
                    { // No
                        ;
                    }
                    else if ( c == 1 )
                    { // Yes
                        callClan( pc );
                    }
                    break;

                case 738: // 経験値を回復するには%0のアデナが必要です。経験値を回復しますか？
                    c = readC();
                    if ( c == 0 )
                    { // No
                        ;
                    }
                    else if ( c == 1 && pc.getExpRes() == 1 )
                    { // Yes
                        int cost = 0;
                        int level = pc.getLevel();
                        int lawful = pc.getLawful();
                        if ( level < 45 )
                        {
                            cost = level * level * 100;
                        }
                        else
                        {
                            cost = level * level * 200;
                        }
                        if ( lawful >= 0 )
                        {
                            cost = ( cost / 2 );
                        }
                        if ( pc.getInventory().consumeItem( L1ItemId.ADENA, cost ) )
                        {
                            pc.resExp();
                            pc.setExpRes( 0 );
                        }
                        else
                        {
                            pc.sendPackets( new S_ServerMessage( 189 ) ); // \f1アデナが不足しています。
                        }
                    }
                    break;

                case 951: // チャットパーティー招待を許可しますか？（Y/N）
                    c = readC();
                    L1PcInstance chatPc = (L1PcInstance)L1World.getInstance()
                            .findObject( pc.getPartyID() );
                    if ( chatPc != null )
                    {
                        if ( c == 0 )
                        { // No
                            chatPc.sendPackets( new S_ServerMessage( 423, pc.getName() ) ); // %0が招待を拒否しました。
                            pc.setPartyID( 0 );
                        }
                        else if ( c == 1 )
                        { // Yes
                            if ( chatPc.isInChatParty() )
                            {
                                if ( chatPc.getChatParty().isVacancy() || chatPc.isGm() )
                                {
                                    chatPc.getChatParty().addMember( pc );
                                }
                                else
                                {
                                    chatPc.sendPackets( new S_ServerMessage( 417 ) ); // これ以上パーティーメンバーを受け入れることはできません。
                                }
                            }
                            else
                            {
                                L1ChatParty chatParty = new L1ChatParty();
                                chatParty.addMember( chatPc );
                                chatParty.addMember( pc );
                                chatPc.sendPackets( new S_ServerMessage( 424, pc
                                        .getName() ) ); // %0がパーティーに入りました。
                            }
                        }
                    }
                    break;

                case 953: // パーティー招待を許可しますか？（Y/N）
                    c = readC();
                    L1PcInstance target = (L1PcInstance)L1World.getInstance()
                            .findObject( pc.getPartyID() );
                    if ( target != null )
                    {
                        if ( c == 0 ) // No
                        {
                            target.sendPackets( new S_ServerMessage( 423, pc.getName() ) ); // %0が招待を拒否しました。
                            pc.setPartyID( 0 );
                        }
                        else if ( c == 1 ) // Yes
                        {
                            if ( target.isInParty() )
                            {
                                // 招待主がパーティー中
                                if ( target.getParty().isVacancy() || target.isGm() )
                                {
                                    // パーティーに空きがある
                                    target.getParty().addMember( pc );
                                }
                                else
                                {
                                    // パーティーに空きがない
                                    target.sendPackets( new S_ServerMessage( 417 ) ); // これ以上パーティーメンバーを受け入れることはできません。
                                }
                            }
                            else
                            {
                                // 招待主がパーティー中でない
                                L1Party party = new L1Party();
                                party.addMember( target );
                                party.addMember( pc );
                                target.sendPackets( new S_ServerMessage( 424, pc
                                        .getName() ) ); // %0がパーティーに入りました。
                            }
                        }
                    }
                    break;

                case 479: // どの能力値を向上させますか？（str、dex、int、con、wis、cha）
                    if ( readC() == 1 )
                    {
                        String s = readS();
                        if ( !( pc.getLevel() - 50 > pc.getBonusStats() ) )
                        {
                            return;
                        }
                        if ( string.Compare( s, "str", true ) == 0 )
                        {
                            // if(l1pcinstance.get_str() < 255)
                            if ( pc.getBaseStr() < 35 )
                            {
                                pc.addBaseStr( (byte)1 ); // 素のSTR値に+1
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) );
                            }
                        }
                        else if ( string.Compare( s, "dex", true ) == 0 )
                        {
                            // if(l1pcinstance.get_dex() < 255)
                            if ( pc.getBaseDex() < 35 )
                            {
                                pc.addBaseDex( (byte)1 ); // 素のDEX値に+1
                                pc.resetBaseAc();
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) ); // 一つの能力値の最大値は25です。他の能力値を選択してください
                            }
                        }
                        else if ( string.Compare( s, "con", true ) == 0 )
                        {
                            // if(l1pcinstance.get_con() < 255)
                            if ( pc.getBaseCon() < 35 )
                            {
                                pc.addBaseCon( (byte)1 ); // 素のCON値に+1
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) ); // 一つの能力値の最大値は25です。他の能力値を選択してください
                            }
                        }
                        else if ( string.Compare( s, "int", true ) == 0 )
                        {
                            // if(l1pcinstance.get_int() < 255)
                            if ( pc.getBaseInt() < 35 )
                            {
                                pc.addBaseInt( (byte)1 ); // 素のINT値に+1
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) ); // 一つの能力値の最大値は25です。他の能力値を選択してください
                            }
                        }
                        else if ( string.Compare( s, "wis", true ) == 0 )
                        {
                            // if(l1pcinstance.get_wis() < 255)
                            if ( pc.getBaseWis() < 35 )
                            {
                                pc.addBaseWis( (byte)1 ); // 素のWIS値に+1
                                pc.resetBaseMr();
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) ); // 一つの能力値の最大値は25です。他の能力値を選択してください
                            }
                        }
                        else if ( string.Compare( s, "cha", true ) == 0 )
                        {
                            // if(l1pcinstance.get_cha() < 255)
                            if ( pc.getBaseCha() < 35 )
                            {
                                pc.addBaseCha( (byte)1 ); // 素のCHA値に+1
                                pc.setBonusStats( pc.getBonusStats() + 1 );
                                pc.sendPackets( new S_OwnCharStatus2( pc ) );
                                pc.sendPackets( new S_CharVisualUpdate( pc ) );
                                pc.save(); // DBにキャラクター情報を書き込む
                            }
                            else
                            {
                                pc.sendPackets( new S_ServerMessage( 481 ) ); // 一つの能力値の最大値は25です。他の能力値を選択してください
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        private void changeClan( ClientThread clientthread, L1PcInstance pc, L1PcInstance joinPc, int maxMember )
        {
            int clanId = pc.getClanid();
            String clanName = pc.getClanname();
            L1Clan clan = L1World.getInstance().getClan( clanName );
            String[] clanMemberName = clan.getAllMembers();
            int clanNum = clanMemberName.Length;

            int oldClanId = joinPc.getClanid();
            String oldClanName = joinPc.getClanname();
            L1Clan oldClan = L1World.getInstance().getClan( oldClanName );
            String[] oldClanMemberName = oldClan.getAllMembers();
            int oldClanNum = oldClanMemberName.Length;
            if ( clan != null && oldClan != null && joinPc.isCrown() && // 自分が君主
                    joinPc.getId() == oldClan.getLeaderId() )
            {
                if ( maxMember < clanNum + oldClanNum )
                { // 空きがない
                    joinPc.sendPackets( // %0はあなたを血盟員として受け入れることができません。
                            new S_ServerMessage( 188, pc.getName() ) );
                    return;
                }
                L1PcInstance[] clanMember = clan.getOnlineClanMember();
                for ( int cnt = 0; cnt < clanMember.Length; cnt++ )
                {
                    clanMember[cnt].sendPackets( new S_ServerMessage( 94, joinPc
                            .getName() ) ); // \f1%0が血盟の一員として受け入れられました。
                }

                for ( int i = 0; i < oldClanMemberName.Length; i++ )
                {
                    L1PcInstance oldClanMember = L1World.getInstance().getPlayer(
                            oldClanMemberName[i] );
                    if ( oldClanMember != null )
                    { // オンライン中の旧クランメンバー
                        oldClanMember.setClanid( clanId );
                        oldClanMember.setClanname( clanName );
                        // 血盟連合に加入した君主はガーディアン
                        // 君主が連れてきた血盟員は見習い
                        if ( oldClanMember.getId() == joinPc.getId() )
                        {
                            oldClanMember.setClanRank( L1Clan.CLAN_RANK_GUARDIAN );
                        }
                        else
                        {
                            oldClanMember.setClanRank( L1Clan.CLAN_RANK_PROBATION );
                        }
                        // DBにキャラクター情報を書き込む
                        oldClanMember.save();
                        clan.addMemberName( oldClanMember.getName() );
                        oldClanMember.sendPackets( new S_ServerMessage( 95,
                                clanName ) ); // \f1%0血盟に加入しました。
                    }
                    else
                    { // オフライン中の旧クランメンバー
                        L1PcInstance offClanMember = CharacterTable
                                .getInstance().restoreCharacter(
                                        oldClanMemberName[i] );
                        offClanMember.setClanid( clanId );
                        offClanMember.setClanname( clanName );
                        offClanMember.setClanRank( L1Clan.CLAN_RANK_PROBATION );
                        offClanMember.save(); // DBにキャラクター情報を書き込む
                        clan.addMemberName( offClanMember.getName() );
                    }
                }
                // 旧クラン削除
                String emblem_file = Convert.ToString( oldClanId );
                //File file = new File( "emblem/" + emblem_file );
                File.Delete( "emblem/" + emblem_file );
                ClanTable.getInstance().deleteClan( oldClanName );
            }
        }

        private static void renamePet( L1PetInstance pet, String name )
        {
            if ( pet == null || name == null )
            {
                throw new NullReferenceException();
            }

            int petItemObjId = pet.getItemObjId();
            L1Pet petTemplate = PetTable.getInstance().getTemplate( petItemObjId );
            if ( petTemplate == null )
            {
                throw new NullReferenceException();
            }

            L1PcInstance pc = (L1PcInstance)pet.getMaster();
            if ( PetTable.isNameExists( name ) )
            {
                pc.sendPackets( new S_ServerMessage( 327 ) ); // 同じ名前がすでに存在しています。
                return;
            }
            L1Npc l1npc = NpcTable.getInstance().getTemplate( pet.getNpcId() );
            if ( string.Compare( pet.getName(), l1npc.get_name(), true ) != 0 )
            {
                pc.sendPackets( new S_ServerMessage( 326 ) ); // 一度決めた名前は変更できません。
                return;
            }
            pet.setName( name );
            petTemplate.set_name( name );
            PetTable.getInstance().storePet( petTemplate ); // DBに書き込み
            L1ItemInstance item = pc.getInventory().getItem( pet.getItemObjId() );
            pc.getInventory().updateItem( item );
            pc.sendPackets( new S_ChangeName( pet.getId(), name ) );
            pc.broadcastPacket( new S_ChangeName( pet.getId(), name ) );
        }

        private void callClan( L1PcInstance pc )
        {
            L1PcInstance callClanPc = (L1PcInstance)L1World.getInstance()
                    .findObject( pc.getTempID() );
            pc.setTempID( 0 );
            if ( callClanPc == null )
            {
                return;
            }
            if ( !pc.getMap().isEscapable() && !pc.isGm() )
            {
                // 周辺のエネルギーがテレポートを妨害しています。そのため、ここでテレポートは使用できません。
                pc.sendPackets( new S_ServerMessage( 647 ) );
                L1Teleport.teleport( pc, pc.getLocation(), pc.getHeading(), false );
                return;
            }
            if ( pc.getId() != callClanPc.getCallClanId() )
            {
                return;
            }

            bool isInWarArea = false;
            int castleId = L1CastleLocation.getCastleIdByArea( callClanPc );
            if ( castleId != 0 )
            {
                isInWarArea = true;
                if ( WarTimeController.getInstance().isNowWar( castleId ) )
                {
                    isInWarArea = false; // 戦争時間中は旗内でも使用可能
                }
            }
            short mapId = callClanPc.getMapId();
            if ( mapId != 0 && mapId != 4 && mapId != 304 || isInWarArea )
            {
                // \f1あなたのパートナーは今あなたが行けない所でプレイ中です。
                pc.sendPackets( new S_ServerMessage( 547 ) );
                return;
            }

            L1Map map = callClanPc.getMap();
            int locX = callClanPc.getX();
            int locY = callClanPc.getY();
            int heading = callClanPc.getCallClanHeading();
            locX += HEADING_TABLE_X[heading];
            locY += HEADING_TABLE_Y[heading];
            heading = ( heading + 4 ) % 4;

            bool isExsistCharacter = false;
            foreach ( L1Object l1object in L1World.getInstance().getVisibleObjects( callClanPc, 1 ) )
            {
                if ( l1object is L1Character )
                {
                    L1Character cha = (L1Character)l1object;
                    if ( cha.getX() == locX && cha.getY() == locY && cha.getMapId() == mapId )
                    {
                        isExsistCharacter = true;
                        break;
                    }
                }
            }

            if ( locX == 0 && locY == 0 || !map.isPassable( locX, locY ) || isExsistCharacter )
            {
                // 障害物があってそこまで移動することができません。
                pc.sendPackets( new S_ServerMessage( 627 ) );
                return;
            }
            L1Teleport.teleport( pc, locX, locY, mapId, heading, true, L1Teleport.CALL_CLAN );
        }

        override
        public String getType()
        {
            return _C_ATTR;
        }
    }
}